package org.example;

import com.alibaba.excel.EasyExcel;
import org.example.nlp.DictionaryEntry;
import com.huaban.analysis.jieba.JiebaSegmenter;
import java.util.*;
import java.util.regex.Pattern;

public class SentimentAnalysis {

    // 声明并初始化 JiebaSegmenter
    private static JiebaSegmenter segmenter = new JiebaSegmenter();
    // 定义存储积极词和消极词的集合（全部转为小写，确保匹配时不区分大小写）
    private static Set<String> positiveWords = new HashSet<>();
    private static Set<String> negativeWords = new HashSet<>();

    // 定义与比亚迪相关的关键词列表
    private static final List<String> bydKeywords = Arrays.asList("比亚迪", "byd");

    /**
     * 从 Excel 文件中加载金融情感词典
     * @param filePath Excel 文件路径，其中：
     *                 sheet2（索引为1）：消极词语
     *                 sheet3（索引为2）：积极词语
     */
    private static void loadFinancialDictionaryFromExcel(String filePath) {
        // 加载消极词汇（sheet2，索引为1）
        List<DictionaryEntry> negativeEntries = EasyExcel.read(filePath)
                .head(DictionaryEntry.class)
                .sheet(1)
                .doReadSync();
        for (DictionaryEntry entry : negativeEntries) {
            if (entry.getWord() != null && !entry.getWord().trim().isEmpty()) {
                negativeWords.add(entry.getWord().trim().toLowerCase());
            }
        }

        // 加载积极词汇（sheet3，索引为2）
        List<DictionaryEntry> positiveEntries = EasyExcel.read(filePath)
                .head(DictionaryEntry.class)
                .sheet(2)
                .doReadSync();
        for (DictionaryEntry entry : positiveEntries) {
            if (entry.getWord() != null && !entry.getWord().trim().isEmpty()) {
                positiveWords.add(entry.getWord().trim().toLowerCase());
            }
        }
    }

    // 使用 Jieba 分词器进行分词
    private static List<String> segment(String sentence) {
        return segmenter.sentenceProcess(sentence);
    }

    // 判断句子是否与比亚迪相关（基于简单关键词匹配）
    private static boolean isBYDRelated(String sentence) {
        for (String keyword : bydKeywords) {
            if (sentence.contains(keyword)) {
                return true;
            }
        }
        return false;
    }

    // 计算单个句子的情感得分
    // 计算方式：如果句子中有情感词，则得分 = (积极词数 - 消极词数) / (积极词数 + 消极词数)
    // 得分范围为 [-1, 1]，若无情感词，则返回 0（中性）
    private static double calculateSentenceSentiment(String sentence) {
        List<String> tokens = segment(sentence);
        int posCount = 0;
        int negCount = 0;
        for (String token : tokens) {
            if (positiveWords.contains(token)) {
                //System.out.println("好的"+token);
                posCount++;
            }
            if (negativeWords.contains(token)) {
                //System.out.println("不好的"+token);
                negCount++;
            }
        }
        int total = posCount + negCount;
        //System.out.println((double) (posCount - negCount) / total);
        if (total == 0) {
            return 0.0;
        }
        return (double) (posCount - negCount) / total;
    }

    // 计算一篇文章（标题和内容合并）的整体情感得分
    // 对于与比亚迪相关的句子赋予更高权重（例如权重2），其他句子权重为1
    // 最终将得分归一化到 [0,1]（0：完全消极，1：完全积极）
    public static double calculateArticleSentiment(String text) {
        // 按中文标点（。！？）分句
        String[] sentences = text.split("[。！？]");
        double totalWeightedScore = 0.0;
        double totalWeight = 0.0;
        for (String sentence : sentences) {
            sentence = sentence.trim();
            if (sentence.isEmpty()) continue;
            double sentenceScore = calculateSentenceSentiment(sentence);
            double weight = isBYDRelated(sentence) ? 5 : 1.5;
            totalWeightedScore += sentenceScore * weight;
            totalWeight += weight;
        }

        double overallScore = totalWeight != 0 ? totalWeightedScore / totalWeight : 0.0;
        // 归一化处理：将 [-1,1] 映射到 [0,1]
        return (overallScore + 1.0) / 2.0;
    }

    public static void main(String[] args) {
        // 设置词典 Excel 文件路径（请根据实际情况修改）
        String dictionaryFilePath = "中文金融情感词典_姜富伟等(2020).xlsx";
        loadFinancialDictionaryFromExcel(dictionaryFilePath);

        // 下面示例继续使用 EasyExcel 读取包含新闻数据的 Excel 文件
        String newsFilePath = "新闻数据_20250207_162924.xlsx";
        List<ArticleData> articles = EasyExcel.read(newsFilePath)
                .head(ArticleData.class)
                .sheet()
                .doReadSync();

        for (ArticleData article : articles) {
            // 将标题和内容合并后进行情感分析
            String combinedText = article.getTitle() + " " + article.getContent();
            double sentimentScore = calculateArticleSentiment(combinedText);
            System.out.println("标题: " + article.getTitle() + " | 情感得分: " + sentimentScore);
            // 根据需要，您可以将情感得分写回 Excel 或存入数据库
        }


    }
}
